﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using RabbitMQ.Client;
using RabbitMQ.Client.Events;
using RabbitMQ.Client.MessagePatterns;

namespace ATPlatforms.RabbitSkin
{
    public class DirectConsumer<T> : BaseProducerConsumer<T>
    {
       public delegate void onReceiveMessage(T message);

        public event onReceiveMessage onMessageReceived;

        public DirectConsumer()
            : base()
        {
            MyExchangeType = ExchangeType.Direct;
        }

        public override bool OnStart(string routingKey)
        {
            string queue = Model.QueueDeclare();

            //TODO we need to be able to bind seperately
            Model.QueueBind(queue, Exchange, routingKey, false, null);
      
            ConsumeDelegate c = new ConsumeDelegate(Consume);
            c.BeginInvoke(queue, null, null);
            
            return true;
        }

        public bool SetupQueue()
        {
            OnStart("");
            return true;
        }

        //non-blocking 
        private delegate void ConsumeDelegate(string queue);

        private void Consume(string queue)
        {
            var subscription = new Subscription(Model, queue, false);
            Running = true;
            while (Running)
            {
                BasicDeliverEventArgs basicDeliveryEventArgs = subscription.Next();
                T messageContent = MessageSerializer.DeSerializeMessage(basicDeliveryEventArgs.Body);

                if (onMessageReceived != null)
                    onMessageReceived.BeginInvoke(messageContent, null, null);

                subscription.Ack(basicDeliveryEventArgs);
            }
        }
    }
}
